package com.umfwechat.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.umpay.spapply.common.ReqMessage;
import com.umpay.spapply.common.ResMessage;
import com.umpay.spapply.common.RetCode;
import com.umpay.spapply.util.StringUtil;
import com.umpay.spapply.xml.XmlData;
import com.umpay.util.HttpUtil;

/**
 * desc:配置费率和风控
 * <p>创建人：zhangxichao 创建日期：2016-10-27 </p>
 * @version V1.0
 */
public class AccFeeAndRiskLimitUtil {
	
	private static Logger logger = LoggerFactory.getLogger(AccFeeAndRiskLimitUtil.class);
	private static RequestUtil requestUtil = new RequestUtil();//向基于Http协议的3.0平台发送同步请求工具类
	
	/**
	 * desc:配置风控限额接口
	 * <p>创建人：zhangxichao , 2016-10-27 下午6:37:21</p>
	 * @param params包含：	需要传的字段					名称				描述
	 * 						String rpid					流水号			* 必传
	 * 						String merid	    		商户号			* 必传
	 * 						String productid	 		产品号			* 必传  		产品编号，如P1540020
	 * 						String tagId	   	   		维度				* 必传		取值:1,2,3,4,5,6;1:银行卡号、2:身份证号、3:手机号、4:用户ID、5:账户号、6:新用户
	 * 						String onceAmountLimit   	单笔限额			* 必传 		50000-对私；500000-对公
	 * 						String hourAmountLimit   	小时限额			* 必传		-1，数值，传-1时表示无限制
	 * 						String dayAmountLimit		日限额   	  		* 必传		200000-对私；1000000-对公
	 * 						String monthAmountLimit		月限额			* 必传    		-1，数值，传-1时表示无限制
	 * 						String hourFreqLimit		小时限次			* 必传    		-1，数值，传-1时表示无限制
	 * 						String dayFreqLimit			日限次   	  		* 必传    		-1，数值，传-1时表示无限制
	 * 						String monthFreqLimit		月限次   	  		* 必传    		-1，数值，传-1时表示无限制
	 * @return	重要返回码：	0000-成功（RetCode.SUCCESS）；
	 * 						00060030-配置文件中URL未取到（RetCode.DATA_NOT_EXISTS）；
	 * 						00250082：传入的参数格式有误
	 * 						00250083：请求参数tag_Id找不到相应维度00250084：查询结果为空
	 * 						00250085：请求参数不完整
	 */
	@SuppressWarnings("unchecked")
	public static ResMessage riskFrontLimit(Map<String, Object> params){
		ResMessage res=new ResMessage();		//返回信息
		// 调用配置风控限额接口
		String url=PropertyUtil.getStrValue("spEnterpriseWeb_config.properties", "RISKFRONT_REST2_LIMIT_URL", "");
		if(StringUtil.isEmpty(url)){
			logger.error("配置文件中未取到调用配置风控限额接口地址，url="+url);
			res.setRetCode(RetCode.DATA_NOT_EXISTS);
			res.setRetMsg("配置文件中未取到调用配置风控限额接口地址");
			return res;
		}
		
		Map<String, Object> resMap=(Map<String, Object>) requestUtil.sendRequestForPost(url, params);	
		if(null==resMap||StringUtil.isEmpty((String) resMap.get(XmlData.RETCODE))){
			res.setRetCode(RetCode.ADDLIMIT_FAILED);
			res.setRetMsg("【配置风控限额】失败");
			return res;
		}				
		res.setRetCode((String) resMap.get(XmlData.RETCODE));
		res.setRetMsg((String) resMap.get(XmlData.RETMSG));
		res.setRpid((String) resMap.get("rpid"));		
		logger.info("【配置风控限额】返回结果res="+res);
		return res;
	}
	
	/**
	 * desc:查询风控限额接口
	 * <p>创建人：zhangxichao , 2016-10-28 下午1:14:28</p>
	 * @param params包含：	需要传的字段					名称				描述
	 * 						String rpid					流水号			* 必传
	 * 						String merid	    		商户号			* 必传
	 * 						String productid	 		产品号			* 必传  		产品编号，如P1540020
	 * 						String tagId	   	   		维度				* 必传		取值:1,2,3,4,5,6;1:银行卡号、2:身份证号、3:手机号、4:用户ID、5:账户号、6:新用户
	 * @return	ResMessage：重要返回码：	0000-成功（RetCode.SUCCESS）；
	 * 									00060030-配置文件中URL未取到（RetCode.DATA_NOT_EXISTS）；
	 * 									00345026-查询风控限额失败(RetCode.QUERYLIMIT_FAILED)
	 * 									00250082：传入的参数格式有误
	 * 									00250083：请求参数tag_Id找不到相应维度00250084：查询结果为空
	 * 									00250085：请求参数不完整
	 * 						resMap:		key						value
	 * 								List<String> retList				限额查询结果信息列表
	 * 									
	 */
	@SuppressWarnings("unchecked")
	public static ResMessage queryFrontLimit(Map<String, Object> params){
		ResMessage res=new ResMessage();		//返回信息
		//调用查询风控限额接口
		String url=PropertyUtil.getStrValue("spEnterpriseWeb_config.properties", "RISKFRONT_REST2_LIMITQUERY_URL", "");
		if(StringUtil.isEmpty(url)){
			logger.error("配置文件中未取到查询风控限额接口地址，url="+url);
			res.setRetCode(RetCode.DATA_NOT_EXISTS);
			res.setRetMsg("配置文件中未取到查询风控限额接口地址");
			return res;
		}
		Map<String, Object> resMap=(Map<String, Object>) requestUtil.sendRequestForPost(url, params);	
		if(null==resMap||StringUtil.isEmpty((String) resMap.get(XmlData.RETCODE))){
			res.setRetCode(RetCode.QUERYLIMIT_FAILED);
			res.setRetMsg("【查询风控限额】失败");
			return res;
		}
		//限额查询结果信息列表
		if(null!=(List<String>) resMap.get("returnList")){
			res.put("retList", (List<String>) resMap.get("returnList"));
		}		
		res.setRetCode((String) resMap.get(XmlData.RETCODE));
		res.setRetMsg((String) resMap.get(XmlData.RETMSG));
		res.setRpid((String) resMap.get("rpid"));		
		logger.info("【查询风控限额】返回结果res="+res);
		return res;
	}
	
	
	/**
	 * desc:配置付款费率
	 * <p>创建人：zhangxichao , 2016-10-27 下午3:51:59</p>
	 * @param req
	 * ReqMessage req 包含：	需要传的字段					名称				描述
	 * 						String rpid					流水号			* 必传	 	10-20位 请求流水
	 * 						String reqDate				请求日期			* 必传		yyyyMMdd
	 * 						String reqTime				请求时间			* 必传		hhmmss
	 * 						String merId	    		商户号			* 必传   		必须是t_mer_inf表中的真实有效值
	 * 						String productId			产品号			* 非必传		必须为真实有效值
	 * 						String actSettlType			记账结算类型		* 必传  		2 非实时
	 * 						String binBankId			发卡行			* 非必传
	 * 						String feeRateType   	   	费率类型			* 必传		10 单笔计算、固定值; 11 单笔计算、固定百分比
	 * 						String minFee   	  		保底费率（分）		* 必传		大于等于0
	 * 						String maxFee   	  		封顶费率（分）		* 必传                  
	 * 						String feeRateValue   	  	费率值			* 必传 		大于等于0;有基于费率类型的交易规则，小数点位数不能大于6
	 * 						String startDate	 		开始生效日期		* 必传  		yyyyMMdd
	 * 						String isReturn	 		          退费是否反手续费	* 必传  		0是 1否
	 * 						String modId	 		          操作员编号	        * 必传  		0-16位字符；标识由谁添加了费率配置
	 
	 
	 * @return	重要返回码：	0000-成功（RetCode.SUCCESS）；
	 * 						00170020-费率配置已存在（RetCode.ACCFEE_EXIST）；
	 * 						BPPE9998，BPPE4001-请求数据有误；
	 * 						00020000-数据库错误；
	 * 						其他-失败（RetCode.ACCFEE_FAILED）
	 * 
	 * 						注：
     *							1、费率类型为10时，则封顶和保底必须配置为0，并且费率值必须为整数；
	 *						2、费率类型为11时，费率值必须小于1； 
	 *						3、如果配置了保底手续费和封顶手续费，则保底手续费必须小于封顶手续费（封顶手续费配成0时表示无穷大）
	 *
	 */
	public static ResMessage configurePayRate(ReqMessage req){
		ResMessage res=new ResMessage();		//返回信息
		//调用配置付款费率接口
		String url=PropertyUtil.getStrValue("spEnterpriseWeb_config.properties", "ACC_FEE_URL", "");
		if(StringUtil.isEmpty(url)){
			logger.error("配置文件中未取到调用配置费率接口地址，url="+url);
			res.setRetCode(RetCode.DATA_NOT_EXISTS);
			res.setRetMsg("配置文件中未取到调用配置费率接口地址");
			return res;
		}
		//将ReqMessage转换为Map<String,Object>，以便调用接口
		Map<String, Object> params=configureRequest(req);
		
		res.setRpid(req.getRpid());
		//调用接口的返回信息
		Map<String,Object> rescon=null;
		try {
			logger.info(apLog(req.getRpid(),"【配置付款费率】httpPostForm2Xml请求数据：", req, ",url=", url));	
			rescon = HttpUtil.httpPostForm2Xml(url, params);
			logger.info(apLog(req.getRpid(),"【配置付款费率】httpPostForm2Xml返回结果：",rescon));
			
		}catch (Exception e) {
			logger.error("调用配置费率接口异常"+e);
			res.setRetCode(RetCode.ACCFEE_FAILED);
			res.setRetMsg("调用配置费率接口异常"+e.getMessage());
			return res;
		}
		if(null==rescon||StringUtil.isEmpty((String) rescon.get(XmlData.RETCODE))){
			logger.info("【配置付款费率】失败,返回值rescon="+rescon);
			res.setRetCode(RetCode.ACCFEE_FAILED);
			res.setRetMsg("调用配置费率接口返回值rescon="+rescon);
			return res;
		}
		
		if(RetCode.SUCCESS.equals(StringUtil.trim(rescon.get(XmlData.RETCODE)))){
			logger.info("【配置付款费率】成功！");			
		}else if(RetCode.ACCFEE_EXIST.equals(StringUtil.trim(rescon.get(XmlData.RETCODE)))){
			logger.info("【配置付款费率】已存在，不需要配置！");		
		}else{
			logger.info("【配置付款费率】失败,返回码"+rescon.get(XmlData.RETCODE));
		}
		res.setRetCode((String)rescon.get(XmlData.RETCODE));
		res.setRetMsg((String) rescon.get(XmlData.RETMSG));
		logger.info("【配置付款费率】返回结果res="+res);
		return res;
	}
	
	/**
	 * desc:将ReqMessage转换为Map<String,Object>，以便调用接口
	 * <p>创建人：zhangxichao , 2016-10-27 下午2:59:20</p>
	 * @param req
	 * @return
	 */
	public static Map<String,Object> configureRequest(ReqMessage req){
			
		//移除reqMap中空的内容 否则会报空指针
		Map<String, Object> reqMap = req.getReqMap();
		List<String> reqKeys = new ArrayList<String>();				//reqMap中值为空的key值放到此list中
		for(Entry<String, Object> e : reqMap.entrySet()){
			if(null == e.getValue()){
				reqKeys.add(e.getKey());
			}
		}
		for(String key: reqKeys){
			reqMap.remove(key);
		}
		//组织参数
		Map<String,Object> params = new HashMap<String,Object>();	//调用接口的请求参数map
		params.putAll(reqMap);
		params.put(XmlData.RPID, req.getRpid());					//请求流水号
		params.put(XmlData.REQDATE, req.getReqDate());				//请求日期
		params.put(XmlData.REQTIME, req.getReqTime());				//请求时间		
		return params;
	}
	
	/**
	 * 字符串拼接记录日志
	 * @param rpid
	 * @param parts
	 * @return
	 */
	public static String apLog(String rpid, Object... parts){
		return ap("rpid[",rpid,"]") + ap(parts);
	}
	/**
	 * 字符串拼接
	 * @param parts
	 * @return
	 */
	public static String ap(Object... parts){
		StringBuilder sb = new StringBuilder();
		for(Object p: parts){
			sb.append(p);
		}
		return sb.toString();
	}
	
}
